
import protoClientHandler
import protoInfos
import struct
import time

from protoInter import copyInf_pb2

#socket处理器管理类
global clients
clients = {}


def respMessage(uname,ids):
    '''
    响应接口数据给客户端
    '''    
    connected = clients.get(uname,None)
    print("respMessage,connected:",connected) # websocket_thread 实例
    if connected:
        for protoId in ids:           

            msg = struct.pack('i',protoId) #写入消息号

            
            #自定义数据通讯
            '''
            inf = protoInfos.getPushInfo(protoId)
            fn = inf.get('fn')
            if fn:
                msg += fn(connected)
            '''
            
            #开始protobuf通讯;客户端也系统通关protobuf接收
            copyInf = copyInf_pb2.CopyInfo()
            copyInf.code = 1001
            timeStr = str(time.time())            
            copyInf.progress = int(timeStr.split(".")[0]) 
            copyInf.desc = "这是一个副本信息"
            copyByte = copyInf.SerializeToString()
            msg += copyByte            
            
            print("--------- 开始推送:",protoId,"copyInf.progress",copyInf.progress)
            connected.sendMessage(msg)

    

def dispatch(uname,protoId,data):
    '''
    通过协议id把来自客户端的消息派发给各个处理器
    '''
    protoId = 10001
    info = protoInfos.getClientInfo(protoId)
    if info:
        '''
        #自定义消息结构体的处理
        fn = info.get('fn',None)
        if not fn:
            raise Exception('请检查id:%s的处理器写法是否正确'%str(protoId))
        values = parseProtoData(info.get('fmt'),data)
        protoMsg = info['cls'](protoId)
        protoMsg.updateValues(values) #把接收到的消息解析成自定义python对象
        fn(protoMsg) #处理函数进行处理
        '''
        ids = info.get("toIds",None)
        print("dispatch:ids",ids)
        if ids:
            respMessage(uname,ids)
    else:
        raise Exception("无法找到id:%s 的处理器."%str(protoId))

def parseProtoData(fmt,data):
    fmtSizes = [struct.calcsize(fmt[i]) for i in range(len(fmt)) ]
    print('parseProtoData:fmtSizes',fmtSizes,'fmt',fmt)
    offset = 0
    idx = 0
    values = []
    for size in fmtSizes:
        if fmt[idx]=='s': #最后一个
            f = str(len(data) - offset)+fmt[idx]
            print("读取最后一个字符串:",f,'offset',offset)
            val = struct.unpack_from(f,data,offset=offset)[0].decode('utf8')  #data[offset:].decode('utf8') 
        else:
            val = struct.unpack_from(fmt[idx],data,offset=offset)[0]            
            offset += size
        idx += 1
        print("parseProtoData: val",val)
        values.append(val)
    print("values:",values)
    return values

def getBodySize(protoId):
    info = protoInfos.getClientInfo(protoId)
    fmt = info.get('fmt')
    size = 0
    for i in range(len(fmt)):        
        size += struct.calcsize(fmt[i]) 
    return size